home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / bbsutil / hsrc_117.zip / KMENU.C < prev    next >
C/C++ Source or Header  |  1990-11-12  |  7KB  |  296 lines

  1. /* kmenu.c */
  2.  
  3. #include <stdio.h>
  4. #include <conio.h>
  5. #include <stdlib.h>
  6. #include <dos.h>
  7. #include "keys.h"
  8. #include "twindow.h"
  9.  
  10. extern int VSG;
  11.  
  12. extern void pascal dcls(void);
  13. extern void pascal dputc(int x, int y, int c);
  14. extern int  pascal dputs(int x, int y, char *s);
  15. extern void pascal dclrwnd(int x1, int y1, int x2, int y2);
  16. extern void pascal dscrollup(int x1, int y1, int x2, int y2);
  17. extern void pascal dscrolldn(int x1, int y1, int x2, int y2);
  18.  
  19. extern void (*helpfunc)();
  20.  
  21. extern unsigned int vbase;
  22. extern unsigned int maxx;
  23. extern unsigned int maxy;
  24. extern unsigned char current_color;
  25. extern unsigned char usemouse;
  26. extern unsigned int videomethod;
  27.  
  28. WINDOW * pascal open_menu(char *mnm,KMENU *mn,int hsel);
  29. int pascal gethmenu(KMENU *mn,WINDOW *hmenu,int hsel);
  30. int pascal getvmn(KMENU *mn,WINDOW *hmenu,int *hsel,int vsel);
  31. int pascal haccent(KMENU *mn,WINDOW *hmenu,int hsel,int vsel);
  32. void pascal dimension(char *sl[],int *ht,int *wd);
  33. void pascal light(KMENU *mn,WINDOW *hmenu,int hsel,int d);
  34. #ifdef USECLOCK
  35.  void pascal print_clock(void);
  36. #endif
  37.  
  38.  
  39. /* Display & process a menu */
  40. int pascal kmenu_select(char *name,KMENU *mn) {
  41.  
  42.     WINDOW *hmenu;
  43.     int sx,sy;
  44.     int hsel=1,vsel;
  45.  
  46.     curr_cursor(&sx,&sy);
  47.     cursor(0,26);
  48.     hmenu=open_menu(name,mn,hsel);
  49.     while(hsel=gethmenu(mn,hmenu,hsel)) {
  50.         vsel=1;
  51.         while(vsel=getvmn(mn,hmenu,&hsel,vsel)) {
  52.             if(vsel>25) {
  53.                 vsel=1;
  54.                 continue;
  55.             }
  56.             delete_window(hmenu);
  57.             set_help("",0,0);
  58.             cursor(sx,sy);
  59.             return (mn+hsel-1)->returnkey[vsel-1];
  60.         }
  61.     }
  62.     delete_window(hmenu);
  63.     set_help("",0,0);
  64.     cursor(sx,sy);
  65.     return 0;
  66. }
  67.  
  68.  
  69. /* Open a horizontal menu */
  70. static WINDOW * pascal open_menu(char *mnm,KMENU *mn,int hsel) {
  71.  
  72.     int i=0;
  73.     WINDOW *hmenu;
  74.  
  75.     set_help("kmenu     ",30,10);
  76.     hmenu=establish_window(0,0,3,80);
  77.     set_border(hmenu,6);
  78.     set_title(hmenu,mnm);
  79.     set_colors(hmenu,ALL,BLUE,AQUA,BRIGHT);
  80.     set_colors(hmenu,ACCENT,WHITE,BLACK,DIM);
  81.     display_window(hmenu);
  82.     while((mn+i)->mname) {
  83.         wcursor(hmenu,(i)*11+2,0);
  84.         wprintf(hmenu,"%-9.9s",(mn+i++)->mname);
  85.     }
  86.     light(mn,hmenu,hsel,1);
  87.     cursor(0,26);
  88.     return hmenu;
  89. }
  90.  
  91. /* Get a horizontal selection */
  92. static int pascal gethmenu(KMENU *mn,WINDOW *hmenu,int hsel) {
  93.  
  94.     int sel;
  95.     WINDOW *wnd;
  96.  
  97.     light(mn,hmenu,hsel,1);
  98.     wnd=hmenu;
  99.     SHOWMOUSE;
  100.     CONFINEMOUSE(wnd);
  101.     while(TRUE) {
  102.         while(!kbhit()) {
  103.           if(usemouse) {
  104.  
  105.                 union REGS rg;
  106.  
  107.                 rg.x.ax=3;
  108.                 int86(0x33,&rg,&rg);
  109.                 move_mouse(rg.x.cx/8,rg.x.dx/8);
  110.                 rg.x.ax=5;
  111.                 rg.x.bx=0;          /* Check left button */
  112.                 int86(0x33,&rg,&rg);
  113.                 if(rg.x.bx) {       /* Button pressed */
  114.                     rg.x.cx/=8;     /* Mouse x */
  115.                     rg.x.dx/=8;     /* Mouse y */
  116.                     if(rg.x.cx==COL && rg.x.dx==ROW) {
  117.                         HIDEMOUSE;
  118.                         return 0;
  119.                     }
  120.                     if(rg.x.cx>COL && rg.x.dx>ROW && rg.x.cx<((COL+WIDTH)-1) && rg.x.dx<((ROW+HEIGHT)-1)) {
  121.                         rg.x.dx=rg.x.cx-COL;    /* rg.x.dx = window x pos of mouse */
  122.                         rg.x.cx=0;
  123.                         while((mn+rg.x.cx)->mname) {
  124.                             if(rg.x.dx>=(rg.x.cx*11+2) && rg.x.dx<=(rg.x.cx*11+2)+11) {
  125.                                 HIDEMOUSE;
  126.                                 light(mn,hmenu,hsel,0);
  127.                                 light(mn,hmenu,rg.x.cx+1,1);
  128.                                 return rg.x.cx+1;
  129.                             }
  130.                             rg.x.cx++;
  131.                         }
  132.                     }
  133.                 }
  134.                 rg.x.ax=3;
  135.                 int86(0x33,&rg,&rg);
  136.                 move_mouse(rg.x.cx/8,rg.x.dx/8);
  137.                 rg.x.ax=5;
  138.                 rg.x.bx=1;
  139.                 int86(0x33,&rg,&rg);
  140.                 if(rg.x.bx) {
  141.                     HIDEMOUSE;
  142.                     return 0;
  143.                 }
  144.               }
  145. #ifdef USECLOCK
  146.               print_clock();
  147. #endif
  148.         }
  149.         HIDEMOUSE;
  150.         switch(sel=get_char()) {
  151.             case FWD:
  152.             case BS:    hsel=haccent(mn,hmenu,hsel,sel);
  153.                         break;
  154.             case ESC:    return 0;
  155.             case '\r':     return hsel;
  156.             case DN:    return hsel;
  157.             default:    putchar (BELL);
  158.                         break;
  159.         }
  160.     }
  161. }
  162.  
  163. /* Pop down a vertical menu */
  164. static int pascal getvmn(KMENU *mn,WINDOW *hmenu,int *hsel,int vsel) {
  165.  
  166.     WINDOW *vmenu;
  167.     int ht=10,wd=20;
  168.     int temp;
  169.     char **mp;
  170.  
  171.     while (1) {
  172.         dimension((mn+*hsel-1)->mselcs,&ht,&wd);
  173.         if(wd+(2+(*hsel-1)*11)>78)temp=79-wd;
  174.         else temp=2+(*hsel-1)*11;
  175.         vmenu=establish_window(temp,2,ht,wd);
  176.         set_colors(vmenu,ALL,BLUE,AQUA,BRIGHT);
  177.         set_colors(vmenu,ACCENT,WHITE,BLACK,DIM);
  178.         set_border(vmenu,4);
  179.         display_window(vmenu);
  180.         mp=(mn+*hsel-1)->mselcs;
  181.         while(*mp) wprintf(vmenu,"\n%s",*mp++);
  182.         vsel=get_selection(vmenu,vsel,"");
  183.         delete_window(vmenu);
  184.         if(vsel==PGUP) vsel=FWD;
  185.         if(vsel==PGDN) vsel=BS;
  186.         if (vsel==FWD || vsel==BS) {
  187.             *hsel=haccent(mn,hmenu,*hsel,vsel);
  188.             vsel=1;
  189.         }
  190.         else
  191.             return vsel;
  192.     }
  193. }
  194.  
  195. /* Manage the horizontal menu selection accent */
  196. static int pascal haccent(KMENU *mn,WINDOW *hmenu,int hsel,int sel) {
  197.  
  198.     switch (sel) {
  199.         case FWD:
  200.             light(mn,hmenu,hsel,0);
  201.             if((mn+hsel)->mname) hsel++;
  202.             else hsel=1;
  203.             light(mn,hmenu,hsel,1);
  204.             break;
  205.         case BS:
  206.             light(mn,hmenu,hsel,0);
  207.             if(hsel==1)    while((mn+hsel)->mname)    hsel++;
  208.             else --hsel;
  209.             light(mn,hmenu,hsel,1);
  210.             break;
  211.         default:
  212.             break;
  213.     }
  214.     return hsel;
  215. }
  216.  
  217. /* Compute a menu's height & width */
  218. static void pascal dimension(char *sl[],int *ht,int *wd) {
  219.  
  220.     unsigned strlen(char *);
  221.  
  222.     *ht=*wd=0;
  223.     while(sl[*ht]) {
  224.         *wd=max(*wd,strlen(sl[*ht]));
  225.         (*ht)++;
  226.     }
  227.     *ht+=2;
  228.     *wd+=2;
  229. }
  230.  
  231. /* Accent a horizontal menu selection */
  232. static void pascal light (KMENU *mn,WINDOW *hmenu,int hsel,int d) {
  233.  
  234.     if(d) reverse_video(hmenu);
  235.     wcursor(hmenu,(hsel-1)*11+2,0);
  236.     wprintf(hmenu,(mn+hsel-1)->mname);
  237.     normal_video(hmenu);
  238.     cursor(0,26);
  239. }
  240.  
  241.  
  242. /*
  243.  
  244. int pascal hkmenu (char **selcs, char *keys, int *start) {
  245.  
  246.     int ky;
  247.     int pos[40];
  248.     int register x,ps;
  249.     int last;
  250.     char temp;
  251.  
  252.     if(!selcs) return 0;
  253.     temp=current_color;
  254.     current_color=BLACK + (WHITE * 16);
  255.     x=0;
  256.     last=1;
  257.     while (x<40 && selcs[x]) {
  258.         pos[x]=last;
  259.         last+=dprintf(pos[x],maxy," %s ",selcs[x]);
  260.         x++;
  261.     }
  262.     if(*start>x-1) *start=0;
  263.     current_color=WHITE + (BLACK * 16);
  264.     ps=*start;
  265.     dprintf(pos[*start],maxy," %s ",selcs[ps]);
  266.     while(TRUE) {
  267.         ky=toupper(get_char());
  268.         switch(ky) {
  269.             case '\r':  ky=keys[ps];
  270.                         goto BreakOut;
  271.             case FWD:
  272.             case BS:
  273.                         current_color=BLACK + (WHITE * 16);
  274.                         dprintf(pos[ps],maxy," %s ",selcs[ps]);
  275.                         if(ky==FWD) {
  276.                             ps++;
  277.                             if(ps>=x) ps=0;
  278.                         }
  279.                         else {
  280.                             ps--;
  281.                             if(ps<0) ps=x-1;
  282.                         }
  283.                         current_color=WHITE + (BLACK * 16);
  284.                         dprintf(pos[ps],maxy," %s ",selcs[ps]);
  285.                         break;
  286.             default:    goto BreakOut;
  287.         }
  288.     }
  289. BreakOut:
  290.     current_color=temp;
  291.     *start=ps;
  292.     return ky;
  293. }
  294.  
  295. */
  296.